from flask import Blueprint, request, send_file
import pandas as pd
from collections import Counter
import os
import jieba
import fitz
import requests
from requests_toolbelt import MultipartEncoder

from entity.Response import success,error
from entity.Info import Info
from entity.Question import Question

dataController = Blueprint('dataController',__name__)

FILE_PATH = './controller/LocalCsv/'
PDF_FILE_FOLDER = './controller/LocalPdf/'
PDF_IMAGE_FOLDER = './controller/LocalImage/'

"""
获取所有可以分析的表
input:
none
output:
none
"""
@dataController.route('/getAllTable',methods=['GET'])
def getAllTable():
    # 指定文件夹路径
    folder_path = FILE_PATH

    # 获取文件夹下的所有文件和文件夹
    all_items = os.listdir(folder_path)

    # 筛选出文件
    files = [item for item in all_items if os.path.isfile(os.path.join(folder_path, item))]
    return success(message='获取可分析列表成功',data=files)

"""
对表格文件进行数据分析
input:
表格文件名称filename
output:
各类疾病数量 词云频率 患者年龄分布 男女比例
"""
@dataController.route('/analysisDataByFile', methods=['GET'])
def analysisDataByFile():
    filename = request.args.get('filename')
    filePath = FILE_PATH + filename
    fileType = filePath.split('.')[-1]

    try:
        if fileType == 'csv':
            df = pd.read_csv(filePath)
        elif fileType == 'xlsx':
            # 将Excel文件读取成 ExcelFile 格式
            xls = pd.ExcelFile(filePath)

            # 获取sheet表的名称
            exchanges = xls.sheet_names
            df = pd.read_excel(filePath, sheet_name=exchanges[0])
    except:
        return error(message='目标表格不存在')

    ### 获取共有多少条数据
    Count = len(df)

    ### 获取各类疾病个数
    try:
        diseaseCount = []
        coloums = ['N','D','G','C','A','H','M','O']
        for coloum in coloums:
            diseaseCount.append(int((df[coloum] == 1).sum()))
    except:
        return error(message='CSV/XLSX文件格式有误')

    ### 获取词云
    try:
        # 对左眼和右眼的关键词列进行处理
        left_keywords_counts = count_keywords(df['Left-Diagnostic Keywords'])
        right_keywords_counts = count_keywords(df['Right-Diagnostic Keywords'])

        # 合并两个Counter对象
        combined_counts = left_keywords_counts + right_keywords_counts

        # 将合并后的Counter对象转换为列表
        # 这里我们将其转换为[(keyword, count), ...]的形式
        keyword_counts_list = list(combined_counts.items())

        # 处理成前端所需要的格式
        wordCloud = []
        for (keyword,count) in keyword_counts_list:
            wordCloud.append({
                'name': keyword,
                'value': count
            })
    except:
        return error(message='CSV/XLSX文件格式有误')

    ### 获取用户年龄分级情况
    try:
        age_counts = Counter()
        for index, row in df.iterrows():
            age = row['Patient Age']
            mi = age
            mx = age
            while mi > int(age / 10) * 10:
                mi = mi - 1
            while mx < (int(age / 10) + 1) * 10:
                mx = mx + 1

            key = str(mi) + '-' + str(mx) + '岁'
            age_counts[key] += 1
        age_counts = list(age_counts.items())
        # 转化为前端需要的格式
        ageCount = []
        for (keyword, count) in age_counts:
            ageCount.append({
                'name': keyword,
                'value':count
            })
    except:
        return error(message='CSV/XLSX文件格式有误')

    ### 获取男女比例
    try:
        gender_counts = Counter()
        for index, row in df.iterrows():
            gender = row['Patient Sex']
            if gender == 'Female':
                gender_counts['女性患者'] += 1
            elif gender == 'Male':
                gender_counts['男性患者'] += 1
            else:
                gender_counts['未知患者'] += 1

        gender_counts = list(gender_counts.items())
        genderCount = []
        for (keyword, count) in gender_counts:
            genderCount.append({
                'name': keyword,
                'value':count
            })
    except:
        return error(message='CSV/XLSX文件格式有误')

    finalResult = {
        'diseaseCount': diseaseCount,
        'wordCloud': wordCloud,
        'ageCount': ageCount,
        'genderCount': genderCount,
        'Count': Count
    }

    return success(message='数据分析成功',data=finalResult)

"""
数据大屏使用接口 获取info表中的年龄分层
input:
none
output:
age list
"""
@dataController.route('/getAgeListFromInfoTable',methods=['GET'])
def getAgeListFromInfoTable():
    infoList = Info.query.all()
    age_counts = Counter()
    for info in infoList:
        age = info.age
        mi = age
        mx = age
        while mi > int(age / 10) * 10:
            mi = mi - 1
        while mx < (int(age / 10) + 1) * 10:
            mx = mx + 1

        key = str(mi) + '-' + str(mx) + '岁'
        age_counts[key] += 1
    age_counts = list(age_counts.items())
    # 转化为前端需要的格式
    ageCount = []
    for (keyword, count) in age_counts:
        ageCount.append({
            'name': keyword,
            'value':count
        })

    # 按照value排序
    ageCount.sort(key=lambda x: x['value'], reverse=True)
    return ageCount

"""
数据大屏使用接口 获取每个疾病的访问量
input:
none
output:
list
"""
@dataController.route('/getHotDiseaseFromQuestionTable',methods=['GET'])
def getHotDiseaseFromQuestionTable():
    diseaseList = ['糖尿病视网膜病变', '青光眼', '白内障', 'AMD', '高血压', '近视', '其他疾病/异常']
    dataList = []
    for disease in diseaseList:
        value = 0
        targetDiseaseList = Question.query.filter(Question.tag.contains(disease)).all()
        for targetDisease in targetDiseaseList:
            value += targetDisease.view
        obj = {
            'name': disease,
            'value': value
        }
        dataList.append(obj)
    return dataList

"""
数据大屏使用接口 获取用户所提问题的词频热度
input:
none
output:
list
"""
@dataController.route('/getWordCloudFormQuestionTable',methods=['GET'])
def getWordCloudFormQuestionTable():
    questionList = Question.query.all()
    counter = Counter()
    for question in questionList:
        words = jieba.cut(question.title)
        for word in words:
            counter[word] += 1
    counterList = list(counter.items())
    dataList = []
    for (keyword, count) in counterList:
        dataList.append({
            'name': keyword,
            'value':count
        })
    return dataList

"""
下载自助诊断的pdf模板
input:
None:
output:
pdf模板
"""
@dataController.route('/downloadPdfTemplate',methods=['GET'])
def downloadPdfTemplate():
    pdf_path = './pdfTemplate.pdf'
    try:
        return send_file(pdf_path, download_name='pdfTemplate.pdf', as_attachment=True)
    except:
        return error(message='文件不存在')

"""
python后端解析pdf文档 并返回用于诊断的关键信息
input:
pdf文件
output:
左右眼文件名 左右眼关键词
"""
@dataController.route('/parsePdf',methods=['POST'])
def parsePDF():
    pdfFile = request.files['file']
    save_path = PDF_FILE_FOLDER + 'uploadPdf.pdf'
    pdfFile.save(save_path)

    doc = fitz.open(save_path)

    # 提取图片
    images = []
    for page_num in range(len(doc)):
        page = doc.load_page(page_num)
        image_list = page.get_images(full=True)
        for image_index, img in enumerate(image_list):
            xref = img[0]  # 图片的引用编号
            base_image = doc.extract_image(xref)
            image_bytes = base_image["image"]  # 图片的二进制数据
            image_ext = base_image["ext"]  # 图片格式
            image_filename = f"image_page_{image_index}.{image_ext}"
            image_path = os.path.join(PDF_IMAGE_FOLDER, image_filename)
            with open(image_path, "wb") as img_file:
                img_file.write(image_bytes)
            images.append(image_filename)
    
    data = {
        'form': {
            'leftFilename': images[0],
            'rightFilename': images[1]
        },
        'leftBase64': return_img_stream(PDF_IMAGE_FOLDER + images[0]),
        'rightBase64': return_img_stream(PDF_IMAGE_FOLDER + images[1]),
    }
    return success(message='pdf解析成功', data=data)

# 定义一个函数来分割关键词并计数
def count_keywords(series):
    keyword_counts = Counter()
    for keywords in series:
        if pd.notna(keywords):  # 确保关键词不为空
            keywords = keywords.split(',')
            for keyword in keywords:
                keyword = keyword.strip()  # 去除可能的空白字符
                if keyword:  # 确保关键词不为空
                    keyword_counts[keyword] += 1
    return keyword_counts

def return_img_stream(img_local_path):
    """
        工具函数:
        获取本地图片流
        :param img_local_path:文件单张图片的本地绝对路径
        :return: 图片流
        """
    import base64
    img_stream = ''
    with open(img_local_path, 'rb') as img_f:
        img_stream = img_f.read()
        img_stream = base64.b64encode(img_stream).decode()
    return img_stream